package com.kongt.netty;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.Map;

import org.ho.yaml.Yaml;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * Hello world!
 *
 */
public class App {

	private int port;

	private String host;
	public App(String host,int port) {
		this.port = port;
		this.host=host;
	}

    public void run() throws Exception{
        //NioEventLoopGroup是用来处理IO操作的多线程事件循环器
        //boss用来接收进来的连接
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //用来处理已经被接收的连接;
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try{
            //是一个启动NIO服务的辅助启动类
            ServerBootstrap sBootstrap = new ServerBootstrap();
            //These EventLoopGroup's are used to handle all the events and IO for ServerChannel and Channel's.
            //为bootstrap设置acceptor的EventLoopGroup和client的EventLoopGroup
            //这些EventLoopGroups用于处理所有的IO事件
            //?这里为什么设置两个group呢?
            sBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new SimpleChatServerInitializer())
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            System.out.println("服务端开启！！！");
            //绑定端口,开始接收进来的连接
            ChannelFuture future = sBootstrap.bind(InetAddress.getByName(host),port).sync();
            //等待服务器socket关闭
            //在本例子中不会发生,这时可以关闭服务器了
            future.channel().closeFuture().sync();
        } finally {
            //
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
            System.out.println("服务端停止！！！");
        }

    }
	public static void main(String[] args) throws Exception {
		
		InputStream yamlInputStream = App.class.getClassLoader().getResourceAsStream("app.yaml");
		BufferedReader reader = new BufferedReader(new InputStreamReader(yamlInputStream));
		Map confMap = (Map) Yaml.load(reader);
		Map remoteMap = (Map)confMap.get("server");
		new App(remoteMap.get("host").toString(), (Integer)remoteMap.get("port")).run();
		reader.close();
		yamlInputStream.close();
		
	}
}
